<script setup>
import { onMounted, reactive, watch } from 'vue'
import * as d3 from 'd3'
import Settings from '../components/settings/index.vue'
import DefaultMode from '../assets/js/KnowledgeGraph/DefaultMode'
import ForceMod from '../assets/js/KnowledgeGraph/ForceMod'
import { studyDataOne } from '../assets/js/data/data'
import { graphType } from '../assets/js/data/assets'
import { ElMessageBox } from 'element-plus'

// 图谱实例
let graphExp = null

// 页面配置
const pageInfo = reactive({
  dialogVisible:false
})

// 图谱配置
const config = reactive({
  theme:false,
  type:0,
  hideNode:[],
  nodeSize:[
    {r:70,fontSize:23},
    {r:50,fontSize:20},
    {r:30,fontSize:17}
  ]
})

onMounted(() => {
  // 初始化图谱
  getGraphData()
})

// 主题切换
watch(
  () => config.theme,
  (newVal) => {
    const theme = newVal ? 'dark' : 'light'
    graphExp?.changeThemeInside(theme)
  }
)

// 监听图谱模式切换
watch(
  () => config.type,
  (newVal) => {
    changeType(newVal)
    config.hideNode = []
  }
)

// 监听节点隐藏状态切换
watch(
  () => config.hideNode,
  (newVal) => {
    graphExp?.changeHideType(newVal)
  }
)

// 监听节点尺寸
watch(
  () => config.nodeSize,
  () => {
    changeType(config.type)
    config.hideNode = []
  },
  {deep:true}
)

// 监听节点大小变化
watch(
  () => config.hideNode,
  (newVal) => {
    graphExp?.changeHideType(newVal)
  }
)

// 图谱模式切换
const changeType = (newVal) => {
  // 原始数据
  const originalDataJSON = JSON.parse(JSON.stringify(studyDataOne))
  // 初始化参数
  const options = {
    data: [],
    originalData: originalDataJSON,
    rootId: 'knowledgeGraph',
    config: {
      theme: config.theme ? 'dark' : 'light',
      type: config.type,
      nodeSize: config.nodeSize,
      handleClick:(event,d)=>{
        const {id,name,level,info} = d
        ElMessageBox.alert(`
          <ul class="d_message_list">
            <li class="d_message_item"><span class="d_label">节点id：</span><span class="d_info">${id}</span></li>
            <li class="d_message_item"><span class="d_label">节点层级：</span><span class="d_info">${level==0?'根节点':`${level}级节点`}</span></li>
            <li class="d_message_item"><span class="d_label">节点信息：</span><span class="d_info">${info}</span></li>
          </ul>
        `, name, {
          confirmButtonText: '确定',
          dangerouslyUseHTMLString:true,
          callback: () => {}
        })
      }
    },
    d3
  }
  if (newVal == 0) {
    // 默认模式-保存后的数据
    const resultDataJSON = JSON.parse(localStorage.getItem('resultDataJSON'))
    options.data = resultDataJSON||originalDataJSON
    graphExp = new DefaultMode(options)
    graphExp.DefaultModeInit()
  }else if(newVal == 1){
    // 力导图模式-保存后的数据
    const forceDataJSON = JSON.parse(localStorage.getItem('forceDataJSON'))
    options.data = forceDataJSON||originalDataJSON
    graphExp = new ForceMod(options)
    graphExp.forceModInit()
  }
}

// 初始化图谱
const getGraphData = async () => {
  if (!graphExp) {
    changeType(config.type)
  }
}

// 打开设置弹窗
const openSettings = () =>{
  pageInfo.dialogVisible = true
}

// 应用设置
const useSettings = (value) =>{
  // console.log(value,'应用设置')
  config.theme = value.theme
  config.type = value.type
  config.hideNode = value.hideNode
  if (isDifferent(config.nodeSize,JSON.parse(JSON.stringify(value.nodeSize)))) {
    config.nodeSize = JSON.parse(JSON.stringify(value.nodeSize))
  }
}

// 判断是否一致
const isDifferent = (a, b) => {
  if (a.length !== b.length) {
    return true
  }
  for (let i = 0; i < a.length; i++) {
    if (a[i].r !== b[i].r || a[i].fontSize !== b[i].fontSize) {
      return true
    }
  }
  return false
}

// 保存
const save = () =>{
  if (graphExp.save) {
    graphExp.handleSave(config.type)
  }
}

// 初始化
const initialize = () => {
  if (graphExp.initialize) {
    graphExp.initialize(studyDataOne)
  }
}

// 元素居中
const setCenter = () => {
  if (graphExp.setCenter) {
    graphExp.setCenter()
  }
}

</script>

<template>
  <div :class="['d_graph_page',config.theme ? 'dark' : 'light']">
    <header class="d_graph_title">
      <span class="d_title">知识图谱 - {{ graphType.find(item => item.id == config.type ).name }}</span>
      <div>
        <el-button type="primary" @click="setCenter" :plain="!config.theme">元素居中</el-button>
        <el-button type="primary" @click="initialize" :plain="!config.theme">初始化</el-button>
        <el-button type="primary" @click="save" :plain="!config.theme">保存</el-button>
        <el-button type="primary" @click="openSettings" :plain="!config.theme">设置</el-button>
      </div>
    </header>
    <main class="d_graph_main" id="knowledgeGraph"></main>

    <Settings v-model:dialogVisible="pageInfo.dialogVisible" :formData="JSON.parse(JSON.stringify(config))" @onSubmit="useSettings" v-if="pageInfo.dialogVisible" />
  </div>
</template>

<style>
.d_graph_page{display:flex;flex-direction:column;height:100vh;overflow: hidden;}
.d_graph_page.light .d_graph_title{color:#333;background-color:#fff;transition: all,0.3s;}
.d_graph_page.dark .d_graph_title{color:#fff;background-color:#333;transition: all,0.3s;}

.d_graph_title{display:flex;align-items:center;justify-content:space-between;box-sizing:border-box;height:65px;padding:0 20px;border-bottom:1px solid #aaa;transition: all,0.3s;}
.d_graph_title .d_title{font-size:18px;font-weight:600;line-height:60px;}

.d_graph_main{flex: 1;}

.d_graph_base{transition:all 0.3s;cursor: url(../assets/images/gripper.cur) 8 8, move;}
.d_graph_base.light{background-color:#eee;}
.d_graph_base.dark{background-color:#333;}

.d_circle{cursor:move;transition:transform 0.3s ease;}
.d_group:hover .d_circle{transform: scale(1.1);transition:transform 0.3s ease;}

.d_text{position:relative;cursor:pointer;transition:transform 0.3s ease;}
.d_text:hover{transform:scale(1.3);transition:transform 0.3s ease;}
.d_group:has(.d_text:hover).d_group:hover .d_circle{transform:scale(1)}

.d_message_item{padding:2px 0;}
.d_message_item .d_label{display:inline-block;width:80px;text-align:right;}

</style>
